import { Controller } from "egg";
const createUserRule = {
  username: "email",
  password: { type: "password", min: 8 },
};
const sendCodeRule = {
  phoneNumber: {
    type: "string",
    format: /^1[3-9]\d{9}$/,
    message: "手机号格式不正确",
  },
};
const loginByCellphoneRule = {
  phoneNumber: {
    type: "string",
    format: /^1[3-9]\d{9}$/,
    message: "手机号格式不正确",
  },
  vericode: { type: "string", format: /^\d{4}$/, message: "验证码格式不正确" },
};
//统一管理错误信息
export const errorCodeInfo = {
  UserValidateError: {
    errno: 101001,
    msg: "用户参数校验失败",
  },
  //创建用户，写入数据库失败
  CreateUserDBError: {
    errno: 101002,
    msg: "用户已存在,请直接登录",
  },
  //用户不存在或者密码错误
  UserLoginError: {
    errno: 101003,
    msg: "用户不存在或者密码错误",
  },
  //登录校验失败
  UserLoginValidateError: {
    errno: 101004,
    msg: "登录校验失败",
  },
  //手机号格式不正确
  CellphoneFormatError: {
    errno: 101005,
    msg: "手机号格式不正确",
  },
  //短时间内禁止多次获取验证码
  SendCodeTooFastError: {
    errno: 101006,
    msg: "短时间内禁止多次获取验证码",
  },
  //验证码
  VericodeError: {
    errno: 101007,
    msg: "验证码错误",
  },
  //gitee登录失败
  GiteeLoginError: {
    errno: 101008,
    msg: "gitee登录失败",
  },
};

export default class UserController extends Controller {
  //校验用户输入
  userValidate(rules) {
    const { ctx } = this;
    // 校验参数
    const error = this.app.validator.validate(rules, ctx.request.body);
    return error;
  }
  //返回四位随机数，封装一个函数
  randomCode() {
    return Math.floor(Math.random() * 9000 + 1000);
  }
  //用户注册
  public async createUserByEmail() {
    const { ctx, service } = this;
    // 校验参数
    const error = this.userValidate(createUserRule);
    if (error) {
      return ctx.helper.error({ ctx, errorType: "UserValidateError", error });
    }
    //判断用户是否存在
    const isUserExist = await service.user.findByUsername(
      ctx.request.body?.username
    );
    if (isUserExist) {
      return ctx.helper.error({ ctx, errorType: "CreateUserDBError" });
    }
    const userData = await service.user.createUserByEmail(ctx.request.body);
    ctx.helper.success({ ctx, data: userData });
  }
  //查看用户
  public async showUserList() {
    const { ctx, service } = this;
    const { id } = ctx.query;
    const userData = await service.user.findById(id);
    try {
      ctx.helper.success({ ctx, data: userData });
    } catch (error) {
      ctx.helper.error({ ctx, errorType: "UserLoginValidateError" });
    }
  }
  //用户登录
  public async userLogin() {
    const { ctx, service } = this;
    const { username, password } = ctx.request.body;
    //判断输入
    const error = this.userValidate(createUserRule);
    if (error) {
      return ctx.helper.error({ ctx, errorType: "UserValidateError", error });
    }
    //查找用户判断是否存在
    const userData = await service.user.findByUsername(username);
    if (!userData) {
      return ctx.helper.error({ ctx, errorType: "UserLoginError" });
    }
    //判断密码是否正确
    const userPwd = await ctx.compare(password, userData.password);
    if (!userPwd) {
      return ctx.helper.error({ ctx, errorType: "UserLoginError" });
    }
    const token = this.app.jwt.sign(
      { username: userData.username },
      this.app.config.jwt.secret,
      { expiresIn: "1d" }
    );
    ctx.helper.success({ ctx, data: { userData, token }, msg: "登录成功" });
  }
  //发送验证码
  public async sendCode() {
    const { ctx } = this;
    //获取手机号
    const { phoneNumber } = ctx.request.body;
    //判断手机号输入
    const cellphoneError = this.userValidate(sendCodeRule);
    //如果有错误，返回错误信息
    if (cellphoneError) {
      return ctx.helper.error({
        ctx,
        errorType: "CellphoneFormatError",
        error: cellphoneError,
      });
    }
    //判断redis中是否有手机号
    const preverCode = await this.app.redis.get(`perverCode-${phoneNumber}`);
    //如果存在，则返回错误信息
    if (preverCode) {
      return ctx.helper.error({ ctx, errorType: "SendCodeTooFastError" });
    }
    //不存在，则发送验证码
    const code = this.randomCode();
    //添加验证码到redis中
    await this.app.redis.set(`perverCode-${phoneNumber}`, code, "ex", 60);
    //返回数据
    ctx.helper.success({ ctx, data: code, msg: "验证码发送成功" });
  }
  //根据手机号登录
  public async loginByCellphone() {
    const { ctx, service } = this;
    const { phoneNumber, vericode } = ctx.request.body;
    //检测用户输入
    const error = this.userValidate(loginByCellphoneRule);
    if (error) {
      return ctx.helper.error({ ctx, errorType: "UserValidateError", error });
    }
    //判断验证码是否正确
    const prevercode = await this.app.redis.get(`perverCode-${phoneNumber}`);
    if (prevercode !== vericode) {
      return ctx.helper.error({ ctx, errorType: "VericodeError" });
    }
    //判断用户是否存在
    const userData = await service.user.findByPhoneNumber(phoneNumber);
    //如果用户存在，就直接登录
    if (userData) {
      const token = this.app.jwt.sign(
        { username: userData.username },
        this.app.config.jwt.secret,
        { expiresIn: "1d" }
      );
      ctx.helper.success({ ctx, data: { userData, token }, msg: "登录成功" });
    } else {
      //如果用户不存在，就创建用户
      const userData = await service.user.createUserByPhone({ phoneNumber });
      const token = this.app.jwt.sign(
        { username: userData.username },
        this.app.config.jwt.secret,
        { expiresIn: "1d" }
      );
      ctx.helper.success({ ctx, data: { userData, token }, msg: "登录成功" });
    }
  }
  //oauth
  public async oauth() {
    const { ctx, app } = this;
    const { cid, redirect_uri } = app.config.giteeOauthConfig;
    const url = `https://gitee.com/oauth/authorize?client_id=${cid}&redirect_uri=${redirect_uri}&response_type=code`;
    ctx.redirect(url);
  }
  //oauthGitee
  public async oauthGitee() {
    const { ctx } = this;
    const { code } = ctx.query;
    try {
      const token = await this.ctx.service.user.loginByGitee(code);
      // ctx.helper.success({ ctx, data: { token }, msg: "登录成功" });
      //TODO 这个页面找不到
      await ctx.render('success.nj', { token });
    } catch (error) {
      ctx.helper.error({ ctx, errorType: "GiteeLoginError" });
    }
  }
}
